package main

import (
	"fmt"
	"github.com/gin-gonic/gin"
	"net/http"
	"os"
	"strings"
	"yhzn/exchange-cabinet-device/cabinet"
	web_socket "yhzn/exchange-cabinet-device/web-socket"
	"zym.com/tools/zconvert/json"
	"zym.com/tools/zconvert/strconv"
	"zym.com/tools/zfile"
)

type Res struct {
	Code   int         `json:"code"`
	Msg    string      `json:"msg"`
	Result interface{} `json:"result,omitempty"`
}

func (r *Res) Set(code int, msg string) {
	r.Code = code
	r.Msg = msg
}

var webServer *gin.Engine

func WebServerLister() {
	gin.SetMode(gin.ReleaseMode)
	webServer = gin.Default()

	webServer.GET("/getStatus", getDevStatus)          // 获取设备状态
	webServer.GET("/getCabinetCount", getCabinetCount) // 获取充电箱数量
	webServer.GET("/getBms", bmsStatus)                // 获取Bms状态
	webServer.GET("/control", control)                 // 设备控制
	webServer.GET("/network", network)                 // 是否有网络
	webServer.GET("/operator", operator)               // 打开运维
	webServer.GET("/setOperator", setOperator)         // 设置运维密码
	webServer.GET("/setDeviceName", setDeviceName)     // 设置设备编码
	webServer.GET("/setTlsFile", setTlsFile)           // 设备证书文件
	webServer.GET("/setCabinetCount", setCabinetCount) // 设备仓位数量

	// ============================WIFI======================================
	webServer.GET("/getSSID", getSSID)         // 获取可用WIFI列表
	webServer.GET("/connectWifi", wifiConnect) // 连接WIFI
	webServer.GET("/searchWifi", searchWifi)   // 搜索WIFI信号

	// =============================静太WBE网站服务================================
	webServer.GET("/", home)
	webServer.GET("/js/*.js", redirect)
	webServer.GET("/css/*.css", redirect)
	webServer.GET("/home/index", redirect)
	//webServer.GET("/MyHome", redirect)
	webServer.GET("/img/*.jpg", redirect)
	webServer.StaticFS("/root", http.Dir("web"))
	//webServer.NoRoute(noRoute)
	if e := webServer.Run(":80"); e != nil {
		os.Exit(0)
	}
}

const redirectUrl = "http://127.0.0.1/root/index.html"

func home(c *gin.Context) {
	c.Redirect(http.StatusMovedPermanently, redirectUrl)
}

func setTlsFile(c *gin.Context) {
	res := Res{}
	defer func() {
		c.JSON(200, res)
	}()
	path := "/media/ztl/"
	d, _ := c.GetQuery("dir")
	caF := path + d + "/ca.pem"
	certF := path + d + "/cert.crt"
	keyF := path + d + "/client.crt"
	cfgF := path + d + "/config.json"
	caF = strings.ReplaceAll(caF, "\\", "/")
	certF = strings.ReplaceAll(certF, "\\", "/")
	keyF = strings.ReplaceAll(keyF, "\\", "/")
	cfgF = strings.ReplaceAll(cfgF, "\\", "/")
	_, e := copyDF(caF, caFile)
	if e != nil {
		res.Set(-1, e.Error())
		return
	}
	_, e = copyDF(certF, certFile)
	if e != nil {
		res.Set(-1, e.Error())
		return
	}
	_, e = copyDF(keyF, keyFile)
	if e != nil {
		res.Set(-1, e.Error())
		return
	}
	_, e = copyDF(cfgF, confFile)

}

func setDeviceName(c *gin.Context) {
	res := Res{}
	code, _ := c.GetQuery("code")
	prefix, _ := c.GetQuery("prefix")
	vendorId, _ := c.GetQuery("vendor_id")
	if code != "" {
		cfg.DevId = code
	}
	if prefix != "" {
		cfg.Prefix = prefix
	}
	if vendorId != "" {
		cfg.VendorId = vendorId
	}
	if code != "" || prefix != "" || vendorId != "" {
		if j, e := json.ToJson(cfg); e == nil {
			zfile.WriteFile(confFile, []byte(j))
		}
	} else {
		res.Set(-1, "all value is empty")
	}
	c.JSON(200, res)
}

func setOperator(c *gin.Context) {
	old, _ := c.GetQuery("old")
	pw, _ := c.GetQuery("pw")
	res := Res{}
	defer func() {
		c.JSON(200, res)
	}()
	if cfg.OperatorPassword != old {
		res.Set(-1, "旧密码不正确")
		return
	}
	cfg.OperatorPassword = pw
	if j, e := json.ToJson(cfg); e == nil {
		if !zfile.WriteFile(confFile, []byte(j)) {
			res.Set(-1, "设置密码失败")
		}
		return
	}
	res.Set(-1, "设置密码失败")
}

func operator(c *gin.Context) {
	pw, _ := c.GetQuery("pw")
	res := Res{}
	if cfg.OperatorPassword == "" {
		cfg.OperatorPassword = "123456"
		if j, e := json.ToJson(cfg); e == nil {
			zfile.WriteFile(confFile, []byte(j))
		}
	}
	if cfg.OperatorPassword != pw {
		res.Set(-1, "密码错误")
	}
	c.JSON(200, res)
}

func redirect(c *gin.Context) {
	fmt.Println(c.Request.RequestURI)
	uri := ""
	if c.Request.RequestURI == "/home/index" {
		c.Redirect(http.StatusMovedPermanently, redirectUrl) //"http://127.0.0.1/root/index.html")
	} else {
		uri = c.Request.RequestURI
		c.Redirect(http.StatusMovedPermanently, "http://127.0.0.1/root"+uri)
	}
}

func bmsStatus(c *gin.Context) {
	no := 0
	strNo, _ := c.GetQuery("no")
	_ = strconv.StrToInt(strNo, &no)
	if no <= len(bms) && bms != nil {
		c.JSON(200, bms[no-1])
	} else {
		c.JSON(200, struct {
			Code int    `json:"code"`
			Msg  string `json:"msg"`
		}{-1, "仓位号不正确"})
	}
}

func getCabinetCount(c *gin.Context) {
	o := struct {
		Count uint8 `json:"count"`
	}{cfg.CabinetSum}
	c.JSON(200, o)
}

func getDevStatus(c *gin.Context) {
	var s = make([]DeviceStatus, cfg.CabinetSum)
	for i := 0; i < int(cfg.CabinetSum); i++ {
		s[i] = getDeviceStatus(byte(i + 1))
	}
	o := struct {
		DeviceId         string `json:"device_id"`         // 设备ID
		QRCode           string `json:"qr_code"`           // 设备二维码
		HelpPhone        string `json:"help_phone"`        // 帮助电话
		Dpi              int    `json:"dpi"`               // 显示屏分辨率
		Yh               int    `json:"yh"`                // 是否云和设备
		AMDCommunication byte   `json:"amd_communication"` // 主板通迅是否正常
		Fire             uint8  `json:"fire"`              // 消防状态 0x00：正常     0x01：报警
		Smoke            uint8  `json:"smoke"`             // 烟感状态 0x00：无烟     0x01：有烟
		Water            uint8  `json:"water"`             // 水浸状态 0x00：无水浸   0x01：有水浸
		T                uint8  `json:"t"`                 // 温度 单位摄氏度，最大127度
		List             []DeviceStatus
	}{cfg.DevId,
		cfg.QrCode,
		cfg.HelpPhone,
		cfg.Dpi,
		cfg.Yh,
		AMDCommunication,
		cab.Fire,
		cab.Smoke,
		cab.Water,
		cab.T,
		s}
	c.JSON(200, o)
}

func control(c *gin.Context) {
	strNo, _ := c.GetQuery("no")
	strOpt, _ := c.GetQuery("opt")
	var no, opt uint8
	var e error
	var b bool
	_ = strconv.StrToUint(strNo, &no)
	_ = strconv.StrToUint(strOpt, &opt)
	switch opt {
	case 1:
		b, _, e = cabinet.OpenDoor(no)
	case 2:
		b, _, e = cabinet.ChargeStart(no)
	case 3:
		b, _, e = cabinet.ChargeStop(no)
	}
	if b && e == nil {
		c.JSON(200, struct {
			Code int    `json:"code"`
			Msg  string `json:"msg"`
		}{0, ""})
	} else {
		c.JSON(200, struct {
			Code int    `json:"code"`
			Msg  string `json:"msg"`
		}{-1, "操作失败"})
	}
}

func network(c *gin.Context) {
	c.JSON(200, gin.H{"is_net": netInfo.NetConnected, "is_mqtt": netInfo.MqttConnect})
	//c.JSON(200, gin.H{"is_net": false, "is_mqtt": false})
}

func setCabinetCount(c *gin.Context) {
	count, _ := c.GetQuery("count")
	_ = strconv.StrToUint(count, &cfg.CabinetSum)
	if cfg.CabinetSum == 0 {
		web_socket.Hint("参数错误", 5)
		return
	}
	if j, e := json.ToJson(cfg); e == nil {
		zfile.WriteFile(confFile, []byte(j))
		web_socket.Write(REFRESH) // 通知web刷新页面
	}
}

// 获取可用WIFI列
func getSSID(c *gin.Context) {
	res := Res{}
	wifiList, e := GetInUseWifiList()
	if e != nil {
		res.Code = -1
		res.Msg = e.Error()
		c.JSON(200, res)
		return
	}
	res.Result = wifiList
	c.JSON(200, res)
}

// 连接WIFI
func wifiConnect(c *gin.Context) {
	ssid, _ := c.GetQuery("ssid")
	pwd, _ := c.GetQuery("pw")
	res := Res{}
	if e := ConnectWifi(ssid, pwd); e != nil {
		res.Code = -1
		res.Msg = e.Error()
	}
	c.JSON(200, res)
}

// 搜索WIFI
func searchWifi(c *gin.Context) {
	res := Res{}
	e := SearchWifi()
	if e != nil {
		res.Code = -1
		res.Msg = e.Error()
	}
	c.JSON(200, res)
	return
}
